package main

import (
	"bytes"
	"fmt"
	"reflect"
)

type order struct {
	ordId      int
	customerId int
}

type employee struct {
	name    string
	id      int
	address string
	salary  int
	country string
}

func main() {
	o := order{
		ordId:      456,
		customerId: 56,
	}
	createQuery(o)

	e := employee{
		name:    "Naveen",
		id:      565,
		address: "Coimbatore",
		salary:  90000,
		country: "India",
	}
	createQuery(e)
	i := 90
	createQuery(i)
}

func createQuery(q interface{}) {
	switch t := reflect.TypeOf(q); t.Kind().String() {
	case "struct":
		fmt.Println(composeSql(q, t.Name()))
	default:
		fmt.Println("unsupported type")
	}
}

func composeSql(q interface{}, name string) string {
	var sql bytes.Buffer
	sql.WriteString(fmt.Sprintf("insert into %s values(", name))
	value := reflect.ValueOf(q)
	numField := value.NumField()

	for i := 0; i < numField; i++ {
		switch v := value.Field(i); v.Kind() {
		case reflect.Int:
			sql.WriteString(fmt.Sprintf("%d", v.Int()))
		case reflect.String:
			sql.WriteString(fmt.Sprintf("\"%     s\"", v.String()))
		}
		if i < numField-1 {
			sql.WriteString(", ")
		} else {
			sql.WriteString(")")
		}
	}

	return sql.String()
}
